/*
*
* 三维场景要素广场，element.js
*
* 主要用来构建各大要素，场景（scene），相机（camera），灯光（light），渲染器（render）
*
* */
define(["Event","Pick","Hawk","camMove","orbit"],function (event,pickup,Hawkeye,CameraMove) {
  
    var Space = function(object){
        
        scope = this;
        this.render = object.update;
        this.dom = object.dom;
        this.scene = object.scene;
        this.array = [];
        this.camera = object.camera;
        this.contArray = {
            pickArray: [],
            oldColor: [],
            id: [],
            time: null,
            otherData: [],
            oneArray:[],
            oneOldColor:[]
        
        };              //一个拾取模型存储器
        this.ort = {
                view:null,
                hawk:null,
        };
        this.modelArr = object.modelArray;
        this.body = {};
        this.temporary = null;
        Orbit = THREE.OrbitControls;
        Handler = new event(this.render);
        Trigger = new pickup(this.modelArr,this.camera);
        Flyto = new CameraMove(scope);
        Hawk = new Hawkeye(this.render);
        Hawk.init(this.dom.parentElement.id,this.camera);
        this.events=Handler;
        object.body = this.body;
        
    };
    Object.assign(Space.prototype,{
        
        init: function(){
            
            //激活拾取
            scope.pick.enable();
            
        },
        orbit: function (camera,dom) {
            if(camera === undefined)return;
            var orts = new Orbit(camera,dom,Handler);
            var ort = new Orbit(Hawk.camera,dom,new event(scope.render));
                ort.enableZoom = false;
                ort.enablePan = false;
            scope.ort.view = orts;
            scope.ort.hawk = ort;
            camera.orbit = orts;
            return orts;
        },
        boxs: function(object,color){
            if(color == undefined) color = new THREE.Color(0x05fd47);
            scope.boxG = newBox(object,color);
                scope.scene.add( scope.boxG );
        },
        monitor:function (e,fun) {
            Trigger.pick(e,function(em){
                fun && fun(em);
            })
        },
        select:function (array) {
            if(array !==undefined)Trigger.arr = array;
            return Trigger.pick;
        },
        dispose:function () {
            if(scope.ort.hawk!==null && scope.ort.view!==null){
                scope.ort.hawk.enableRotate = false;
                scope.ort.view.enableRotate = false;
                scope.ort.hawk.dispose();
                scope.ort.view.dispose();
            }else{
                return;
            }
        },
        enable:function () {
            if(scope.ort.hawk!==null && scope.ort.view!==null){
                scope.ort.hawk.enableRotate = true;
                scope.ort.view.enableRotate = true;
                scope.ort.hawk.enabledPose();
                scope.ort.view.enabledPose();
            }else{
                return;
            }
        },
        reset:function () {
            Trigger.arr = scope.modelArr;
        },
       
        
        pick: {
                enable:function () {
                    //拾取事件
                    Handler.addEvent(scope.dom,"mousedown", function Pickdowm(e){
                        Trigger.pick(e,function(em){
                            Handler.mouseMonitor(e);
                            if(em.length>0){
                                //相机焦点
                                // if(e.button==2){
                                //     var m = em[0].point;
                                //     scope.ortChange.change(m);
                                // }
                            }
        
                        });
                    });
                    Handler.addEvent(scope.dom,"mouseup", function Pickup(e){
                        var po = Handler.mouseMonitor(e);
                        Trigger.pick(e,function(em){
                            if(po.enable){
                            if(em.length>0){
                                scope.tickling.add(em[0].object);
                                scope.body = Model.body = em[0].object;
                                scope.temporary = em[0].object;
                                //相机焦点
                                // if(e.button==0){
                                //     var m = em[0].point;
                                //     scope.ortChange.change(m);
                                // }
                                //xconsole.log(scope.body);
                            }else{
                                scope.tickling.remove();
                                scope.body = Model.body = {};
                                scope.temporary = null;
                            }
                        }});
                        
        
                    });
                    Handler.addEvent(scope.dom,"dblclick",function flyto(e){
                        var po = scope.temporary;
                        if(po && e.buttons ==0){
                            Flyto.cameraMoving(po);
                        }else{
                        
                        }
                    });
                },
                remove:function () {
                    Handler.removeEvent(scope.dom,"mousedown", "Pickdowm",false);
                    Handler.removeEvent(scope.dom,"dblclick", "flyto",false);
                    Handler.removeEvent(scope.dom,"mouseup", "Pickup",false);
                    console.log("%c改事件已经清除","color:green");
                }
        },
        tickling:{
            add:function (params,color) {
                if(color == undefined)color = 0x4285f4;
                var contArray = scope.contArray;
                var reset = contArray.oneArray[0];
                var object = params;
                if (object !== undefined){
                    var id = object.id;
                    var flag = contArray.id.indexOf(id);
                    if ( flag==-1 ){
                        var oldColor = object.material.color;
                        if(reset!==undefined){
                            scope.tickling.remove(reset);
                        }
                        contArray.id.push(id);
                        contArray.oneArray.push(object);
                        contArray.oneOldColor.push(oldColor);
                        object.material.color = new THREE.Color(color);
                        scope.boxs(object,0x05fd47);
                    }
                }
                else{
                    scope.tickling.remove(reset);
                }
            },
            remove:function(reset) {
                var object;
                var borders = scope.boxG;
                reset !== undefined? object = reset : object = scope.contArray.oneArray[0];
                if(!object)return;
                object.material.color = scope.contArray.oneOldColor[0];
                scope.contArray.oneArray.length = 0;
                scope.contArray.oneOldColor.length = 0;
                scope.contArray.id.length = 0;
                
                scope.scene.remove(borders);
                scope.boxG = null;
            }
        },
        ortChange:{
            change:function(m){
                scope.ort.target.copy(m.clone());
                
            },
            reset: function(){
                scope.ort.target.copy(new THREE.Vector3());
            }
        },
        
        
        
        
        
        
        
        
        
        
    });
    var scope,Handler,Orbit,Trigger,Hawk,Flyto;
    function newBox(object,color){
        var box = new THREE.BoxHelper( object, color );
        var position = box.geometry.attributes.position;
        var points = position.array;
        var vectorArray = [];
        var groups = new THREE.Group();
            groups.name = "pickBorders";
        var material = new THREE.LineBasicMaterial({
            color: color,         //mesh.material.color
            depthTest : false,
            transparent : true
        });
        var len = points.length;
        for(var i = 0; i<len;i+=3){
            var vectors = new THREE.Vector3(points[i],points[i+1],points[i+2]);
            vectorArray.push(vectors);
        }
        var vectorArrays = [
            [vectorArray[0], vectorArray[1]],
            [vectorArray[0], vectorArray[3]],
            [vectorArray[0], vectorArray[4]],
            [vectorArray[2], vectorArray[1]],
            [vectorArray[2], vectorArray[3]],
            [vectorArray[2], vectorArray[6]],
            [vectorArray[5], vectorArray[1]],
            [vectorArray[5], vectorArray[4]],
            [vectorArray[5], vectorArray[6]],
            [vectorArray[7], vectorArray[4]],
            [vectorArray[7], vectorArray[3]],
            [vectorArray[7], vectorArray[6]]
        ];
        var length = vectorArrays.length;
        for(var j = 0; j <length; j++){
            var geom = new THREE.Geometry();
            var end = vectorArrays[j][1];
            var start = vectorArrays[j][0];
            var X = Number(end.x - start.x);
            var Y = Number(end.y - start.y);
            var Z = Number(end.z - start.z);
            var maxLength = Math.max(Math.max(Math.abs(X),Math.abs(Y)),Math.abs(Z));
            var segments = maxLength/0.5;
            var deltX = X/segments;
            var deltY = Y/segments;
            var deltZ = Z/segments;
            var newPoint = new THREE.Vector3(vectorArrays[j][0].x,vectorArrays[j][0].y,vectorArrays[j][0].z);
            var long = Math.ceil(segments)+1;
            for( var k = 0; k < long; k++){
                if(k!=0){
                    if(k<segments){
                        newPoint.x += deltX;
                        newPoint.y += deltY;
                        newPoint.z += deltZ;
                        geom.vertices.push(newPoint.clone());
                    }else{
                        geom.vertices.push(end);
                    }
                }else{
                    geom.vertices.push(start);
                }
            }
            var borderlines = new THREE.LineSegments(geom, material);
            groups.add(borderlines);
        }
        return groups;
    }
    
    return Space;
});